/*
* 题目描述
X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
地宫的入口在左上角，出口在右下角。
小明被带到地宫的入口，国王要求他只能向右或向下行走。
走过某个格子时，如果那个格子中的宝贝价值比小明手中任意宝贝价值都大，小明就可以拿起它（当然，也可以不拿）。
当小明走到出口时，如果他手中的宝贝恰好是k件，则这些宝贝就可以送给小明。
请你帮小明算一算，在给定的局面下，他有多少种不同的行动方案能获得这k件宝贝。

【数据格式】
输入一行3个整数，用空格分开：n m k (1<=n,m<=50, 1<=k<=12)
接下来有 n 行数据，每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
要求输出一个整数，表示正好取k个宝贝的行动方案数。该数字可能很大，输出它对 1000000007 取模的结果。

例如，输入：
2 2 2
1 2
2 1
程序应该输出：
2

再例如，输入：
2 3 2
1 2 3
2 1 5
程序应该输出：
14

资源约定：
峰值内存消耗（含虚拟机） < 256M
CPU消耗 < 2000ms

请严格按要求输出，不要画蛇添足地打印类似：“请您输入…” 的多余内容。

所有代码放在同一个源文件中，调试通过后，拷贝提交该源码。
注意：不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意：主类的名字必须是：Main，否则按无效代码处理。
* dfs + 回溯
* */


import java.util.Scanner;

public class 第九题 {
    public static int ans = 0;
    public static int n;
    public static int m;
    public static int k;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        k = sc.nextInt();
        sc.nextLine();

        int[][] array = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                array[i][j] = sc.nextInt();
            }
            sc.nextLine();
        }
        int[] a = new int[k+1];
        for (int i = 0; i < k+1; i++) {
            a[i] = 0;
        }
        dfs(array, 0, 0, 0, a);
        System.out.println(ans%1000000007);
    }

    public static void dfs(int[][] array, int x, int y, int cur, int[] a) {
        // cur 当前拿到第几个了
        if (x >= n || y >= m || cur > k) { // 出口
            return;
        }
        if (cur == k-1 && x == n - 1 && y == m - 1) {
            if(check(a,array[n - 1][m - 1])){
                ans++;
                return;
            }else {
                return;
            }
        }
        if (cur == k && x == n - 1 && y == m - 1) {
            ans++;
            return;
        }
        //先判断能不能拿 不能拿的话就只能往下走了
        if (check(a, array[x][y])) { //可以拿,也可以选择不拿
            //拿
            //System.out.println("ok2");
            a[cur] = array[x][y];
            dfs(array, x + 1, y, cur + 1, a);
            dfs(array, x, y+1, cur+1, a);
            //不拿 记得要回溯
            a[cur] = 0;
            dfs(array, x + 1, y, cur, a);
            dfs(array, x, y+1, cur, a);
        } else { // 不可拿
            dfs(array, x + 1, y, cur, a);
            dfs(array, x, y + 1, cur, a);
        }
    }

    private static boolean check(int[] a, int value) {
        for (int i = 0; i < k; i++) {
            if (value <= a[i]) {
                return false;
            }
        }
        return true;
    }
}
